//-------------------------------------------------------------------
//	Copyright (c) 2010-2012  Zhirnov Andrey
//	This file is part of the "UXGEN" project.
//	See copyright notice in "Engine.h".
//-------------------------------------------------------------------

#ifndef _UX_META_DATA_H
#define _UX_META_DATA_H

#include "MetaObject.h"
#include "EngineTypes.h"

namespace Engine
{
namespace UXTypes
{
	
	class CMetaSetIterator;
	class CMetaStructIterator;
	class CMetaAddIterator;
	class CMetaArrayIterator;
	
	typedef void (CALLBACK *PResizeProc_t)(void *pArr, usize uNewSize);
	typedef bool (CALLBACK *PObjectConstructProc_t)(CMetaSetIterator *&pIter, void *pParam, const char *pParams);
	

	
	//
	// Meta Data Base Type
	//

	class _EXPORT_ IMetaBaseType
	{
	protected:
		string				_sName;
		usize				_uSize;
		uint				_uOffset;
		e_value::type const	_eType;

	public:
		IMetaBaseType(const char *pName, uint uOffset, usize uSize, e_value::type eType);
		virtual ~IMetaBaseType() {}

		uint			GetSize()	const	{ return _uSize; }
		uint			GetOffset()	const	{ return _uOffset; }
		e_value::type	GetType()	const	{ return _eType; }
		const string &	GetName()	const	{ return _sName; }

		virtual bool SetValue(void *pObj, const void * const pValue, e_value::type eType) const;
		virtual bool GetValue(void *pObj, void * pValue, e_value::type eType) const;
		virtual bool GetValue(void *pObj, string &sValue) const;
		virtual bool AddField(const void *pObj, const void *pField, const char *pName, e_value::type eType);
		virtual bool GetField(const string &sName, IMetaBaseType *&pField) const;
		virtual bool GetField(uint uNumb, IMetaBaseType *&pField);
	};
	


	//
	// Meta Data Custom Object Interface
	//

	class IMetaCustomObject
	{
	public:
		virtual bool SetValue(void *pObj, const void * const pValue, e_value::type eType) = 0;
		virtual bool GetValue(void *pObj, void * pValue, e_value::type eType) = 0;
		virtual bool GetValue(void *pObj, string &sValue) = 0;
		virtual bool AddField(const void *pObj, const void *pField, const char *pName, e_value::type eType) = 0;
		virtual bool GetField(const string &sName, IMetaBaseType *&pField) = 0;
		virtual bool GetField(uint uNumb, IMetaBaseType *&pField) = 0;
		virtual void Free() = 0;
	};



	//
	//	Meta Data Default Type
	//

	template <typename T, e_value::type E>
	class _EXPORT_ CMetaDefType : public IMetaBaseType
	{
		friend class CMetaUtils;

	private:
		CMetaDefType(const CMetaDefType &cObj);
		virtual ~CMetaDefType();

		void _SetValue(void *pObj, T tValue)  const;
		void _GetValue(void *pObj, T &tValue) const;

	public:
		CMetaDefType(const char *pName, uint uOffset);

		virtual bool SetValue(void *pObj, const void * const pValue, e_value::type eType) const;
		virtual bool GetValue(void *pObj, void * pValue, e_value::type eType) const;
		virtual bool GetValue(void *pObj, string &sValue) const;
	};

	
	typedef	CMetaDefType< bool,   e_value::BOOL   >		CMetaBoolType;
	typedef	CMetaDefType< int8,   e_value::INT8   >		CMetaInt8Type;
	typedef	CMetaDefType< int16,  e_value::INT16  >		CMetaInt16Type;
	typedef	CMetaDefType< int32,  e_value::INT32  >		CMetaInt32Type;
	typedef	CMetaDefType< int64,  e_value::INT64  >		CMetaInt64Type;
	typedef	CMetaDefType< float,  e_value::FLOAT  >		CMetaFloatType;
	typedef	CMetaDefType< double, e_value::DOUBLE >		CMetaDoubleType;



	//
	// Meta Data String Type
	//

	class _EXPORT_ CMetaStringType : public IMetaBaseType
	{
		friend class CMetaUtils;

	private:
		CMetaStringType(const CMetaStringType &cObj);
		virtual ~CMetaStringType();

	public:
		CMetaStringType(const char *pName, uint uOffset);

		virtual bool SetValue(void *pObj, const void * const pValue, e_value::type eType) const;
		virtual bool GetValue(void *pObj, void * pValue, e_value::type eType) const;
		virtual bool GetValue(void *pObj, string &sValue) const;
	};



	//
	// Meta Data Array Type
	//

	class _EXPORT_ CMetaArrayType : public IMetaBaseType
	{
		friend class CMetaUtils;
		friend class CMetaObject;
		friend class CMetaArrayIterator;

	private:
		uint			_uElemSize;		// element size with align
		IMetaBaseType *	_pElemType;

		PResizeProc_t	_pResizeProc;


		CMetaArrayType(const CMetaArrayType &cObj);
		virtual ~CMetaArrayType();

	public:
		CMetaArrayType(const char *pName, uint uOffset, uint uSize, IMetaBaseType *pType);

		bool SetProcs(PResizeProc_t pResize);
		bool GetIterator(CMetaArrayIterator *&pIter, void *pObj);
	};



	//
	// Meta Array Iterator
	//

	class _EXPORT_ CMetaArrayIterator
	{
	private:
		struct arrayDummy
		{
			void *	pMemory;
			uint	uCount,
					uSize;
		};

		CMetaArrayType	 *	_pType;
		const arrayDummy  *	_pArr;
		uint				_uNumb;

	public:
		CMetaArrayIterator(CMetaArrayType *pMtArr, void *pObj);
		CMetaArrayIterator(const CMetaArrayIterator &iter);
		~CMetaArrayIterator();
		
		void Free();

		CMetaArrayIterator & operator = (const CMetaArrayIterator &right);
		
		e_value::type		 GetElemType()	const	{ return _pType->_pElemType->GetType(); }

		bool SelectElem(uint uNumb);
		bool Resize(uint uNewSize);
		uint GetCurNumb()			const	{ return _uNumb; }
		uint GetCount()				const	{ return _pArr->uCount; }

		bool SetValue(const string &sName, const void *pData, e_value::type eType) const;
		bool SetValue(const void *pData, e_value::type eType) const;
		
		// for values only //
		bool GetValue(void *pValue, e_value::type eType) const;
		bool GetValue(string &sValue)					 const;

		// for objects only //
		bool GetValue(const string &sName, void *pValue, e_value::type eType) const;
		bool GetValue(uint uFieldNumb, void *pValue, e_value::type eType) const;
		bool GetValue(const string &sName, string &sValue) const;
		bool GetValue(uint uFieldNumb, string &sValue) const;

		bool GetSetIterator(CMetaSetIterator *&pIter)	 const;
		bool GetArrIterator(CMetaArrayIterator *&pIter)	 const;
		bool GetStrIterator(CMetaStructIterator *&pIter) const;
	};



	//
	// Meta Data Struct Type
	//

	class _EXPORT_ CMetaStructType : public IMetaBaseType
	{
		friend class CMetaUtils;
		friend class CMetaObject;
		friend class CMetaArrayIterator;

	private:
		PResizeProc_t	_pResizeProc;
		uint8			_uAlign;


		CMetaStructType(const CMetaStructType &cObj);
		virtual ~CMetaStructType();

	public:
		CMetaStructType(const char *pName, uint uOffset/*, const char *pParams*/);

		uint8 GetAlign()	const		{ return _uAlign; }

		bool SetProcs(PResizeProc_t pResize);
		bool GetIterator(CMetaStructIterator *&pIter, void *pObj);
	};



	//
	// Meta Struct Iterator
	//

	class _EXPORT_ CMetaStructIterator
	{
	private:
		struct arrayDummy
		{
			void *	pMemory;
			uint	uCount,
					uSize;
		};

		CMetaStructType	 *	_pType;
		arrayDummy		 *	_pArr;
		uint				_uPos;			// pos in binary array

	public:
		CMetaStructIterator(CMetaStructType *pMtStr, void *pObj);
		CMetaStructIterator(const CMetaStructIterator &iter);
		~CMetaStructIterator();
		
		void Free();

		CMetaStructIterator & operator = (const CMetaStructIterator &right);
		
		e_value::type		 GetElemType()	const	{ return e_value::UNKNOWN; }

		bool PushBackValue(const void *pData, e_value::type eType) const;
	};



	//
	// Meta Data Custom Type
	//

	class _EXPORT_ CMetaCustomType : public IMetaBaseType
	{
		friend class CMetaUtils;

	private:
		string				_sName;
		IMetaCustomObject	*_pObj;

		CMetaCustomType(const CMetaCustomType &cObj);
		CMetaCustomType(const char *pName, uint uOffset, uint uSize);
		virtual ~CMetaCustomType();

	public:
		virtual bool SetValue(void *pObj, const void * const pValue, e_value::type eType) const;
		
		virtual bool GetValue(void *pObj, void * pValue, e_value::type eType) const;
		virtual bool GetValue(void *pObj, string &sValue) const;
		
		virtual bool GetField(const string &sName, IMetaBaseType *&pField) const;
		virtual bool GetField(uint uNumb, IMetaBaseType *&pField);
		
		bool SetProc(IMetaCustomObject *pObj);
	};



	//
	// Meta Data Object interface
	//

	class _EXPORT_ IMetaObject
	{
	private:
		string		_sName;				// type name

	public:
		IMetaObject(const char *pName): _sName(pName) {}
		virtual ~IMetaObject() {}

		const string &	GetName()		const	{ return _sName; }

		virtual CMetaObject	 *	GetMetaObject() = 0;
	};



	//
	// Meta Data Object
	//

	class _EXPORT_ CMetaObject : public IMetaObject
	{
		friend class CMetaClass;
		friend class CMetaObjectType;
		friend class CMetaAddIterator;

	private:
		string					_sName;				// type name
		array< IMetaBaseType *>	_aFields;
		PObjectConstructProc_t	_pCreateProc;
		uint					_uSize;

		CMetaObject(const CMetaObject &cObj, const char *pName, uint uSize = 0);
		CMetaObject(const char *pName, uint uSize);

		bool _CopyFields(const CMetaObject &cObj);

	public:
		virtual ~CMetaObject();

		uint			GetSize()		const	{ return _uSize; }

		CMetaObject	 *	GetMetaObject()			{ return this; }

		void AddField(IMetaBaseType *pField)	{ _aFields.PushBack( pField ); }

		bool GetField(const string &sName, IMetaBaseType *&pField) const;
		bool GetField(uint uNumb, IMetaBaseType *&pField);
		bool GetObj(const string &sName, IMetaBaseType *&pObj, uint &uOffset) const;
		
		void SetCreateProc(PObjectConstructProc_t pProc)	{ _pCreateProc = pProc; }
		bool CreateObject(CMetaSetIterator *&piter, void *pParam = nullptr, const char *pParams = nullptr);
	};



	//
	// Meta Data Typedef
	//

	class _EXPORT_ CMetaTypedef : public IMetaObject
	{
		friend class CMetaUtils;

	private:
		CMetaObject		*_pType;

		CMetaTypedef(const char *pName, CMetaObject *pObj): IMetaObject(pName), _pType(pObj) {}

	public:
		~CMetaTypedef()	{}

		CMetaObject	 *	GetMetaObject()			{ return _pType; }
	};



	//
	// Meta Data Object Type
	//

	class _EXPORT_ CMetaObjectType : public IMetaBaseType
	{
		friend class CMetaUtils;
		friend class CMetaObject;
		friend class CMetaClass;

	private:
		string			_sName;
		CMetaObject	*	_pType;
		
		CMetaObjectType(const CMetaObjectType &cObj);
		virtual ~CMetaObjectType();

	public:
		CMetaObjectType(const char *pName, uint uOffset, CMetaObject *pObj);

		virtual bool GetField(const string &sName, IMetaBaseType *&pField) const;
		virtual bool GetField(uint uNumb, IMetaBaseType *&pField);
		CMetaObject *GetObj()	const	{ return _pType; }
	};



	//
	// Meta Data Utils
	//

	class CMetaUtils
	{
	public:
		template <typename T, e_value::type E>
		static bool ConvertValue(const void * const pValue, e_value::type eType, T &tRes);
		
		template <typename T, e_value::type E>
		static bool ConvertValue(const T &tValue, e_value::type eType, void *pRes);
		
		static bool Create(const string &sTypeName, CMetaSetIterator *&pIter, void *pParam, const char *pParams);
		static bool CopyObject(IMetaBaseType *pObj, IMetaBaseType *&pNewObj);
		static bool Typedef(const char *pTypeName, const char *pNewName);
		static void Free(IMetaBaseType *&pObj);
	};



	//
	// Meta Data Set Value Iterator
	//

	class _EXPORT_ CMetaSetIterator
	{
		friend class CMetaClass;
		friend class CMetaArrayIterator;

	private:
		CMetaObjectType		*_pBase;
		IMetaBaseType		*_pCurObj;
		const void			*_pObj;
		uint				_uOffset;
		
		CMetaSetIterator(const void *pObj, CMetaObjectType *pBase);

	public:
		CMetaSetIterator(const CMetaSetIterator &cIter);
		~CMetaSetIterator();

		void Free();

		CMetaSetIterator &	operator = (const CMetaSetIterator &right);
		const string	 &	GetObjName() const;
		const void		 *	GetObjPtr()  const		{ return _pObj; }
		CMetaObjectType	 *	GetObjType() const		{ return _pBase; }

		bool FindObject(const string &sName);
		bool SetValue(const string &sName, const void * pValue, e_value::type eType) const;
		bool SetValue(const void *pValue, e_value::type eType) const;
		bool SetValue(uint uNumb, const void *pValue, e_value::type eType) const;
		bool GetArrayIterator(const string &sName, CMetaArrayIterator *&pIter) const;
		bool GetStructIterator(const string &sName, CMetaStructIterator *&pIter) const;

		bool GetValue(const string &sName, const void *pValue, e_value::type eType) const;
	};
	

	template <>
	struct TAutoPtrStrategy< CMetaSetIterator >
	{
		static void Delete(CMetaSetIterator *ptr)	{ ptr->Free(); }
	};

	typedef TAutoPtr< CMetaSetIterator >	CMetaSetIteratorPtr;



	//
	// Meta Data Add Field Iterator
	//

	class _EXPORT_ CMetaAddIterator
	{
		friend class CMetaClass;

	private:
		struct TMetaInfo
		{
			CMetaObject		*pMtObj;
			const void		*pClObj;
			///
			TMetaInfo(): pMtObj(nullptr), pClObj(nullptr) {}
			TMetaInfo(CMetaObject *mt, const void *cl): pMtObj(mt), pClObj(cl) {}
		};

		TDynStack< TMetaInfo >		_sObjStack;
		
		CMetaAddIterator(CMetaObject *pMObj, const void *pObj);

	public:
		CMetaAddIterator(const CMetaAddIterator &cIter);
		~CMetaAddIterator();

		void Free();

		CMetaAddIterator &	operator = (const CMetaAddIterator &right);

		template <typename T>
		void AddField(const T *pField, const char *pName);

		//bool AddCustom(const void *pObj, const char *pName, IMetaCustomObject *pCustObj);

		bool Pop()		{ return _sObjStack.Pop(); }
	};

	
	template <>
	struct TAutoPtrStrategy< CMetaAddIterator >
	{
		static void Delete(CMetaAddIterator *ptr)	{ ptr->Free(); }
	};

	typedef TAutoPtr< CMetaAddIterator >	CMetaAddIteratorPtr;



	//
	// Meta Data Class
	//

	class _EXPORT_ CMetaClass
	{
	private:
		CMetaObjectType	  *	_pObject;
		bool				_bInit;

		CMetaClass(const CMetaClass &);

		static bool _Compare(const string &sName);

	public:
		CMetaClass();
		~CMetaClass();

		bool Create(const char *pName, const char *pTypeName, uint uSize = 0);
		bool Create(const char *pName, const CMetaClass &cObj, uint uSize = 0);
		bool Create(const char *pName, uint uSize);

		void SetCreateProc(PObjectConstructProc_t pProc);

		bool IsInit()	const	{ return _bInit; }

		CMetaAddIterator *	GetAddIter(const void *pObj)	const;
		CMetaSetIterator *	GetSetIter(const void *pObj)	const;

		CMetaObjectType	 *	GetObject()	const	{ return _pObject; }

		bool CreateObject(CMetaSetIterator *&pIter, void *pParam = nullptr, const char *pParams = nullptr);

		static bool s_InitBaseTypes();
	};



// --------------------------------------------------------------- //

	IMetaBaseType * CreateMetaObject(const char *pName, usize uOffset, usize uSize, TDate &obj);
	IMetaBaseType * CreateMetaObject(const char *pName, usize uOffset, usize uSize, vec2 &obj);
	IMetaBaseType * CreateMetaObject(const char *pName, usize uOffset, usize uSize, dvec2 &obj);
	IMetaBaseType * CreateMetaObject(const char *pName, usize uOffset, usize uSize, ivec2 &obj);
	IMetaBaseType * CreateMetaObject(const char *pName, usize uOffset, usize uSize, uvec2 &obj);
	IMetaBaseType * CreateMetaObject(const char *pName, usize uOffset, usize uSize, vec3 &obj);
	IMetaBaseType * CreateMetaObject(const char *pName, usize uOffset, usize uSize, dvec3 &obj);
	IMetaBaseType * CreateMetaObject(const char *pName, usize uOffset, usize uSize, ivec3 &obj);
	IMetaBaseType * CreateMetaObject(const char *pName, usize uOffset, usize uSize, uvec3 &obj);
	IMetaBaseType * CreateMetaObject(const char *pName, usize uOffset, usize uSize, vec4 &obj);
	IMetaBaseType * CreateMetaObject(const char *pName, usize uOffset, usize uSize, dvec4 &obj);
	IMetaBaseType * CreateMetaObject(const char *pName, usize uOffset, usize uSize, ivec4 &obj);
	IMetaBaseType * CreateMetaObject(const char *pName, usize uOffset, usize uSize, uvec4 &obj);
	IMetaBaseType * CreateMetaObject(const char *pName, usize uOffset, usize uSize, u8_vec4 &obj);
	IMetaBaseType * CreateMetaObject(const char *pName, usize uOffset, usize uSize, frect &obj);
	IMetaBaseType * CreateMetaObject(const char *pName, usize uOffset, usize uSize, drect &obj);
	IMetaBaseType * CreateMetaObject(const char *pName, usize uOffset, usize uSize, irect &obj);
	IMetaBaseType * CreateMetaObject(const char *pName, usize uOffset, usize uSize, urect &obj);
	IMetaBaseType * CreateMetaObject(const char *pName, usize uOffset, usize uSize, fquat &obj);
	IMetaBaseType * CreateMetaObject(const char *pName, usize uOffset, usize uSize, dquat &obj);
	IMetaBaseType * CreateMetaObject(const char *pName, usize uOffset, usize uSize, transform_f &obj);
	IMetaBaseType * CreateMetaObject(const char *pName, usize uOffset, usize uSize, transform_d &obj);

	IMetaBaseType * CreateMetaObject(const char *pName, usize uOffset, usize uSize, string &obj);
	IMetaBaseType * CreateMetaObject(const char *pName, usize uOffset, usize uSize, binary_buffer_t &obj);
	
	IMetaBaseType * CreateMetaArray(const char *pName, usize uOffset, PResizeProc_t pProc, usize uSize, IMetaBaseType *pType);

	template <typename T, typename S, typename A>
	IMetaBaseType * CreateMetaObject(const char *pName, usize uOffset, usize uSize, array<T,S,A> &obj)
	{
		return CreateMetaArray( pName, uOffset, &array<T,S,A>::s_Resize, uSize,
								CreateMetaObjectTempl<T>( nullptr, 0, sizeof(T) ) ); 
	}




// ---------------------- CMetaArrayIterator --------------------- //
	
	inline CMetaArrayIterator & CMetaArrayIterator::operator = (const CMetaArrayIterator &right)
	{
		_pType	= right._pType;
		_pArr	= right._pArr;
		_uNumb	= right._uNumb;
		return *this;

	}


	inline bool CMetaArrayIterator::SelectElem(uint uNumb)
	{
		if ( _pArr->uCount <= uNumb )
			return false;

		_uNumb = uNumb;
		return true;
	}


	inline bool CMetaArrayIterator::Resize(uint uNewSize)
	{
		_pType->_pResizeProc( (void *)_pArr, uNewSize );
		_uNumb = 0;
		return true;
	}


	inline bool CMetaArrayIterator::SetValue(const string &sName, const void *pData, e_value::type eType) const
	{
		IMetaBaseType	*temp = nullptr;

		if ( !_pType->_pElemType->GetField( sName, temp ) )	
			return false;

		return temp->SetValue( (int8*)_pArr->pMemory + _pType->_uElemSize * _uNumb, pData, eType );
	}


	inline bool CMetaArrayIterator::SetValue(const void *pData, e_value::type eType) const
	{
		return _pType->_pElemType->SetValue( (int8*)_pArr->pMemory + _pType->_uElemSize * _uNumb, pData, eType );
	}


	inline bool CMetaArrayIterator::GetValue(void *pValue, e_value::type eType) const
	{
		return _pType->_pElemType->GetValue( (int8*)_pArr->pMemory + _pType->_uElemSize * _uNumb, pValue, eType );
	}


	inline bool CMetaArrayIterator::GetValue(string &sValue) const
	{
		return _pType->_pElemType->GetValue( (int8*)_pArr->pMemory + _pType->_uElemSize * _uNumb, sValue );
	}


	inline bool CMetaArrayIterator::GetValue(const string &sName, void *pValue, e_value::type eType) const
	{
		IMetaBaseType	*temp = nullptr;

		if ( !_pType->_pElemType->GetField( sName, temp ) )
			return false;

		return temp->GetValue( (int8*)_pArr->pMemory + _pType->_uElemSize * _uNumb, pValue, eType );
	}
	

	inline bool CMetaArrayIterator::GetValue(uint uFieldNumb, void *pValue, e_value::type eType) const
	{
		IMetaBaseType	*temp = nullptr;

		if ( !_pType->_pElemType->GetField( uFieldNumb, temp ) )
			return false;
		
		return temp->GetValue( (int8*)_pArr->pMemory + _pType->_uElemSize * _uNumb, pValue, eType );
	}


	inline bool CMetaArrayIterator::GetValue(const string &sName, string &sValue) const
	{
		IMetaBaseType	*temp = nullptr;

		if ( !_pType->_pElemType->GetField( sName, temp ) )
			return false;

		return temp->GetValue( (int8*)_pArr->pMemory + _pType->_uElemSize * _uNumb, sValue );
	}
	

	inline bool CMetaArrayIterator::GetValue(uint uFieldNumb, string &sValue) const
	{
		IMetaBaseType	*temp = nullptr;

		if ( !_pType->_pElemType->GetField( uFieldNumb, temp ) )
			return false;

		return temp->GetValue( (int8*)_pArr->pMemory + _pType->_uElemSize * _uNumb, sValue );
	}



// ----------------------- CMetaSetIterator ---------------------- //

	inline CMetaSetIterator & CMetaSetIterator::operator = (const CMetaSetIterator &right)
	{
		_pBase		= right._pBase;
		_pCurObj	= right._pCurObj;
		_pObj		= right._pObj;
		_uOffset	= right._uOffset;
		return *this;
	}


	inline const string & CMetaSetIterator::GetObjName() const
	{
		return _pBase->GetObj()->GetName();
	}


	inline bool CMetaSetIterator::FindObject(const string &sName)
	{
		_pCurObj = _pBase;
		return _pBase->GetObj()->GetObj( sName, _pCurObj, _uOffset );
	}


	inline bool CMetaSetIterator::SetValue(const string &sName, const void * pValue, e_value::type eType) const
	{
		IMetaBaseType	*temp = nullptr;

		if ( !_pCurObj->GetField( sName, temp ) )	
			return false;

		return temp->SetValue( (uint8*)_pObj + _uOffset, pValue, eType );
	}
	

	inline bool CMetaSetIterator::SetValue(const void *pValue, e_value::type eType) const
	{
		return _pCurObj->SetValue( (uint8*)_pObj + _uOffset, pValue, eType );
	}
	

	inline bool CMetaSetIterator::SetValue(uint uNumb, const void *pValue, e_value::type eType) const
	{
		IMetaBaseType	*temp = nullptr;

		if ( !_pCurObj->GetField( uNumb, temp ) )
			return false;

		return temp->SetValue( (uint8*)_pObj + _uOffset, pValue, eType );
	}
	

	inline bool CMetaSetIterator::GetArrayIterator(const string &sName, CMetaArrayIterator *&pIter) const
	{
		IMetaBaseType	*temp = nullptr;

		if ( !_pCurObj->GetField( sName, temp ) || temp->GetType() != e_value::ARRAY )
			return false;

		return ((CMetaArrayType *)temp)->GetIterator( pIter, (int8*)_pObj + _uOffset );
	}


	inline bool CMetaSetIterator::GetStructIterator(const string &sName, CMetaStructIterator *&pIter) const
	{
		IMetaBaseType	*temp = nullptr;

		if ( !_pCurObj->GetField( sName, temp ) || temp->GetType() != e_value::STRUCT )
			return false;

		return ((CMetaStructType *)temp)->GetIterator( pIter, (int8*)_pObj + _uOffset );
	}



// ----------------------- CMetaAddIterator ---------------------- //

	inline CMetaAddIterator & CMetaAddIterator::operator = (const CMetaAddIterator &right)
	{
		_sObjStack = right._sObjStack;
		return *this;
	}
	

	template <typename T>
	inline void CMetaAddIterator::AddField(const T *pField, const char *pName)
	{
		TMetaInfo	&	s_info	 = _sObjStack.Get();
		const usize		u_offset = ptr_offset( pField, s_info.pClObj );
		const usize		u_size	 = sizeof( *pField );

		return s_info.pMtObj->AddField( CreateMetaObjectTempl<T>( pName, u_offset, u_size ) );
	}


	/*inline bool CMetaAddIterator::AddCustom(const void *pObj, const char *pName, IMetaCustomObject *pCustObj)
	{
		TMetaInfo	&s_info	= _sObjStack.Get();
		return s_info.pMtObj->AddCustom( pName, (uint)( (uint8*)pObj - (uint8*)s_info.pClObj ), pCustObj );
	}*/

//-------------------------------------------------------------------

}	// Engine
}	// UXTypes

#endif	// _UX_META_DATA_H